<template>
  <div class="project-detail" v-loading="loading">
    <!-- 页面头部 -->
    <div class="page-header">
      <div class="header-left">
        <div class="project-title">
          <div class="project-icon">
            <span>{{ project.name?.charAt(0).toUpperCase() }}</span>
          </div>
          <div class="title-info">
            <h2>{{ project.name }}</h2>
            <p class="description">{{ project.description || '暂无描述' }}</p>
          </div>
        </div>
      </div>
      <div class="header-right">
        <el-tag :type="getStatusType(project.status)" size="large">
          {{ getStatusText(project.status) }}
        </el-tag>
        <el-button-group>
          <el-button 
            type="primary" 
            :loading="project.status === 'deploying'"
            :disabled="project.status === 'deploying'"
            @click="handleDeploy"
          >
            <i class="fas fa-rocket"></i>
            立即部署
          </el-button>
          <el-button @click="showSettings = true">
            <i class="fas fa-cog"></i>
            项目设置
          </el-button>
        </el-button-group>
      </div>
    </div>

    <!-- 主要内容区 -->
    <div class="content-grid">
      <!-- 左侧内容 -->
      <div class="main-content">
        <!-- 部署历史 -->
        <div class="deploy-history card">
          <div class="card-header">
            <h3>部署历史</h3>
            <el-button link @click="fetchDeployLogs">
              <i class="fas fa-sync"></i>
              刷新
            </el-button>
          </div>
          
          <div class="timeline">
            <div v-for="log in deployLogs" :key="log._id" class="timeline-item">
              <div class="timeline-icon" :class="log.status">
                <i :class="getStatusIcon(log.status)"></i>
              </div>
              <div class="timeline-content">
                <div class="timeline-header">
                  <div class="header-left">
                    <span class="time">{{ formatDate(log.startTime) }}</span>
                    <el-tag size="small" :type="getStatusType(log.status)">
                      {{ getStatusText(log.status) }}
                    </el-tag>
                  </div>
                  <div class="header-right">
                    <el-button 
                      v-if="log.status === 'success'" 
                      size="small"
                      @click="handleRollback(log)"
                    >
                      <i class="fas fa-history"></i>
                      回滚到此版本
                    </el-button>
                  </div>
                </div>
                <div class="deploy-info">
                  <span class="branch">
                    <i class="fas fa-code-branch"></i>
                    {{ log.branch }}
                  </span>
                  <span class="commit" v-if="log.commitId">
                    <i class="fas fa-code-commit"></i>
                    {{ log.commitId.slice(0, 7) }}
                  </span>
                  <span class="deployer" v-if="log.deployedBy">
                    <i class="fas fa-user"></i>
                    {{ log.deployedBy.username }}
                  </span>
                </div>
                <div class="deploy-logs">
                  <div v-for="(entry, index) in log.logs" :key="index"
                       :class="['log-entry', entry.level]">
                    <span class="log-time">{{ formatTime(entry.timestamp) }}</span>
                    <span class="log-message">{{ entry.message }}</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 右侧内容 -->
      <div class="side-content">
        <!-- 项目信息卡片 -->
        <div class="project-info card">
          <div class="card-header">
            <h3>项目信息</h3>
          </div>
          <div class="info-list">
            <div class="info-item">
              <label>仓库地址</label>
              <div class="value-with-copy">
                <span>{{ project.repositoryUrl }}</span>
                <el-button link @click="copyToClipboard(project.repositoryUrl)">
                  <i class="fas fa-copy"></i>
                </el-button>
              </div>
            </div>
            <div class="info-item">
              <label>部署分支</label>
              <span>{{ project.deploymentConfig?.branch || 'master' }}</span>
            </div>
            <div class="info-item">
              <label>构建命令</label>
              <span>{{ project.deploymentConfig?.buildCommand || 'npm run build' }}</span>
            </div>
            <div class="info-item">
              <label>部署路径</label>
              <span>{{ project.deploymentConfig?.serverConfig?.path }}</span>
            </div>
            <div class="info-item">
              <label>最后部署</label>
              <span>{{ formatDate(project.lastDeployTime) || '暂未部署' }}</span>
            </div>
          </div>
        </div>

        <!-- 服务器状态卡片 -->
        <div class="server-status card">
          <div class="card-header">
            <h3>服务器状态</h3>
            <el-tag :type="serverOnline ? 'success' : 'danger'" size="small">
              {{ serverOnline ? '在线' : '离线' }}
            </el-tag>
          </div>
          <div class="status-metrics">
            <div class="metric">
              <div class="metric-header">
                <span>CPU 使用率</span>
                <span class="metric-value">{{ serverMetrics.cpu }}%</span>
              </div>
              <el-progress 
                :percentage="serverMetrics.cpu" 
                :color="getCpuColor"
                :stroke-width="8"
              />
            </div>
            <div class="metric">
              <div class="metric-header">
                <span>内存使用率</span>
                <span class="metric-value">{{ serverMetrics.memory }}%</span>
              </div>
              <el-progress 
                :percentage="serverMetrics.memory" 
                :color="getMemoryColor"
                :stroke-width="8"
              />
            </div>
            <div class="metric">
              <div class="metric-header">
                <span>磁盘使用率</span>
                <span class="metric-value">{{ serverMetrics.disk }}%</span>
              </div>
              <el-progress 
                :percentage="serverMetrics.disk" 
                :color="getDiskColor"
                :stroke-width="8"
              />
            </div>
          </div>
        </div>

        <!-- 部署统计卡片 -->
        <div class="deploy-stats card">
          <div class="card-header">
            <h3>部署统计</h3>
          </div>
          <div class="stats-grid">
            <div class="stat-item">
              <div class="stat-value">{{ deployStats.total }}</div>
              <div class="stat-label">总部署次数</div>
            </div>
            <div class="stat-item">
              <div class="stat-value success">{{ deployStats.success }}</div>
              <div class="stat-label">成功部署</div>
            </div>
            <div class="stat-item">
              <div class="stat-value failed">{{ deployStats.failed }}</div>
              <div class="stat-label">失败部署</div>
            </div>
            <div class="stat-item">
              <div class="stat-value">{{ deployStats.successRate }}%</div>
              <div class="stat-label">成功率</div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 项目设置对话框 -->
    <el-dialog
      v-model="showSettings"
      title="项目设置"
      width="800px"
      destroy-on-close
    >
      <project-settings 
        :project="project"
        @save="handleSettingsSave"
        @cancel="showSettings = false"
      />
    </el-dialog>

    <!-- 回滚确认对话框 -->
    <el-dialog
      v-model="showRollbackDialog"
      title="确认回滚"
      width="400px"
    >
      <div class="rollback-dialog-content">
        <i class="fas fa-exclamation-triangle warning-icon"></i>
        <p>确定要回滚到此版本吗？</p>
        <p class="warning-text">此操作将覆盖当前部署的版本</p>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="showRollbackDialog = false">取消</el-button>
          <el-button type="warning" @click="confirmRollback" :loading="rolling">
            确认回滚
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { useRoute } from 'vue-router'
import { ElMessage } from 'element-plus'
import { projectApi } from '../../api/project'
import ProjectSettings from '../../components/ProjectSettings.vue'
import { useAuthStore } from '../../store/auth'
import { wsClient } from '../../services/websocket.service'

const route = useRoute()
const project = ref({})
const deployLogs = ref([])
const showSettings = ref(false)
const showRollbackDialog = ref(false)
const loading = ref(false)
const rolling = ref(false)
const serverOnline = ref(true)
const selectedLog = ref(null)
const serverMetrics = ref({
  cpu: 45,
  memory: 60,
  disk: 75
})
const authStore = useAuthStore()
const wsHandlers = ref(new Map()); // 存储 WebSocket 处理函数

// 部署统计
const deployStats = computed(() => {
  const total = deployLogs.value.length
  const success = deployLogs.value.filter(log => log.status === 'success').length
  const failed = deployLogs.value.filter(log => log.status === 'failed').length
  const successRate = total ? Math.round((success / total) * 100) : 0

  return { total, success, failed, successRate }
})

// 获取状态类型
const getStatusType = (status) => {
  const typeMap = {
    idle: 'info',
    deploying: 'warning',
    success: 'success',
    failed: 'danger'
  }
  return typeMap[status] || 'info'
}

// 获取状态图标
const getStatusIcon = (status) => {
  const iconMap = {
    running: 'fas fa-spinner fa-spin',
    success: 'fas fa-check',
    failed: 'fas fa-times'
  }
  return iconMap[status] || 'fas fa-question'
}

// 获取状态文本
const getStatusText = (status) => {
  const textMap = {
    idle: '就绪',
    deploying: '部署中',
    success: '部署成功',
    failed: '部署失败'
  }
  return textMap[status] || status
}

// 格式化日期和时间
const formatDate = (date) => date ? new Date(date).toLocaleString() : '暂无'
const formatTime = (date) => new Date(date).toLocaleTimeString()

// 复制到剪贴板
const copyToClipboard = async (text) => {
  try {
    await navigator.clipboard.writeText(text)
    ElMessage.success('已复制到剪贴板')
  } catch (error) {
    ElMessage.error('复制失败')
  }
}

// 获取指标颜色
const getCpuColor = (percentage) => {
  if (percentage < 60) return '#67C23A'
  if (percentage < 80) return '#E6A23C'
  return '#F56C6C'
}

const getMemoryColor = (percentage) => {
  if (percentage < 70) return '#67C23A'
  if (percentage < 90) return '#E6A23C'
  return '#F56C6C'
}

const getDiskColor = (percentage) => {
  if (percentage < 80) return '#67C23A'
  if (percentage < 90) return '#E6A23C'
  return '#F56C6C'
}

// 处理部署
const handleDeploy = async () => {
  try {
    await projectApi.deployProject(project.value._id);
    project.value.status = 'deploying';
    ElMessage.success('部署已开始');
    
    // 添加部署超时检查
    const deployTimeout = setTimeout(() => {
      if (project.value.status === 'deploying') {
        project.value.status = 'failed';
        ElMessage.error('部署超时');
        fetchDeployLogs();
      }
    }, 600000); // 10分钟超时

    // 监听状态变化以清除超时检查
    const statusHandler = (status) => {
      if (status === 'success' || status === 'failed') {
        clearTimeout(deployTimeout);
        wsClient.off('deployStatus', statusHandler);
      }
    };
    wsClient.on('deployStatus', statusHandler);

  } catch (error) {
    ElMessage.error('部署失败: ' + error.message);
  }
};

// 处理回滚
const handleRollback = (log) => {
  selectedLog.value = log;
  showRollbackDialog.value = true;
}

const confirmRollback = async () => {
  if (!selectedLog.value) return;
  
  try {
    rolling.value = true;
    await projectApi.rollbackDeploy(project.value._id, selectedLog.value._id);
    showRollbackDialog.value = false;
    ElMessage.success('回滚已开始');
    // 更新项目状态
    project.value.status = 'deploying';
  } catch (error) {
    ElMessage.error(error.response?.data?.message || '回滚失败');
  } finally {
    rolling.value = false;
  }
}

// 保存设置
const handleSettingsSave = async (settings) => {
  try {
    const updatedProject = await projectApi.updateProject(project.value._id, settings)
    project.value = updatedProject
    showSettings.value = false
    ElMessage.success('设置已保存')
  } catch (error) {
    ElMessage.error('保存失败: ' + error.message)
  }
}

// 获取项目详情
const fetchProjectDetails = async () => {
  try {
    loading.value = true
    const [projectData, logsData] = await Promise.all([
      projectApi.getProjectById(route.params.id),
      projectApi.getProjectLogs(route.params.id)
    ])
    project.value = projectData
    deployLogs.value = logsData
    
    // 设置WebSocket连接
    setupWebSocket()
  } catch (error) {
    ElMessage.error('获取项目详情失败: ' + error.message)
  } finally {
    loading.value = false
  }
}

// 获取部署日志
const fetchDeployLogs = async () => {
  try {
    const logs = await projectApi.getProjectLogs(route.params.id)
    deployLogs.value = logs
  } catch (error) {
    ElMessage.error('获取部署日志失败: ' + error.message)
  }
}

// WebSocket处理
const setupWebSocket = () => {
  if (!project.value?._id) {
    console.error('项目ID不存在，无法建立WebSocket连接');
    return;
  }

  // 确保token存在
  const token = authStore.token;
  if (!token) {
    console.error('Token不存在，无法建立WebSocket连接');
    return;
  }

  // 存储处理函数，避免重复添加
  const deployLogHandler = (log) => {
    console.log('收到部署日志:', log);
    if (!deployLogs.value[0]) {
      deployLogs.value.unshift({
        logs: [],
        status: 'running',
        startTime: new Date()
      });
    }
    deployLogs.value[0].logs.push(log);
  };

  const deployStatusHandler = (status) => {
    console.log('收到部署状态更新:', status);
    project.value.status = status;
    if (status === 'success' || status === 'failed') {
      setTimeout(fetchDeployLogs, 1000);
    }
  };

  const serverStatusHandler = (metrics) => {
    console.log('收到服务器状态更新:', metrics);
    serverMetrics.value = metrics;
    serverOnline.value = true;
  };

  // 连接状态处理
  wsClient.on('disconnect', () => {
    console.log('WebSocket断开连接');
    serverOnline.value = false;
  });

  wsClient.on('reconnect', () => {
    console.log('WebSocket重新连接成功');
    serverOnline.value = true;
  });

  // 存储并注册处理函数
  wsHandlers.value.set('deployLog', deployLogHandler);
  wsHandlers.value.set('deployStatus', deployStatusHandler);
  wsHandlers.value.set('serverStatus', serverStatusHandler);

  wsHandlers.value.forEach((handler, type) => {
    wsClient.on(type, handler);
  });

  // 建立连接
  wsClient.connect(project.value._id, token);
};

onMounted(() => {
  fetchProjectDetails()
})

onUnmounted(() => {
  // 移除所有处理函数
  wsHandlers.value.forEach((handler, type) => {
    wsClient.off(type, handler);
  });
  wsClient.disconnect();
})
</script>

<style scoped>
.project-detail {
  min-height: 100vh;
  background: var(--background-primary);
}

.page-header {
  background: var(--background-secondary);
  border-bottom: 1px solid var(--border-color);
  padding: var(--spacing-lg) var(--spacing-xl);
  margin-bottom: var(--spacing-xl);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.project-title {
  display: flex;
  align-items: center;
  gap: var(--spacing-lg);
}

.project-icon {
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--primary-light);
  color: var(--primary-color);
  border-radius: var(--radius-lg);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-medium);
}

.title-info h2 {
  margin: 0;
  margin-bottom: var(--spacing-xs);
}

.description {
  color: var(--text-secondary);
  font-size: var(--font-size-sm);
}

.content-grid {
  display: grid;
  grid-template-columns: 1fr 360px;
  gap: var(--spacing-xl);
  padding: 0 var(--spacing-xl);
  max-width: 1440px;
  margin: 0 auto;
}

.card {
  background: var(--background-secondary);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  margin-bottom: var(--spacing-xl);
}

.card-header {
  padding: var(--spacing-lg);
  border-bottom: 1px solid var(--border-color);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.card-header h3 {
  margin: 0;
  font-size: var(--font-size-lg);
}

.timeline {
  padding: var(--spacing-lg);
}

.timeline-item {
  display: flex;
  gap: var(--spacing-lg);
  margin-bottom: var(--spacing-xl);
  position: relative;
}

.timeline-icon {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.timeline-icon.success { 
  background: var(--success-color);
  color: white;
}

.timeline-icon.failed { 
  background: var(--error-color);
  color: white;
}

.timeline-icon.running { 
  background: var(--warning-color);
  color: white;
}

.timeline-content {
  flex: 1;
  background: var(--background-tertiary);
  border-radius: var(--radius-lg);
  padding: var(--spacing-lg);
}

.timeline-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--spacing-md);
}

.deploy-info {
  display: flex;
  gap: var(--spacing-lg);
  color: var(--text-tertiary);
  font-size: var(--font-size-sm);
  margin-bottom: var(--spacing-md);
}

.deploy-logs {
  font-family: var(--font-family-mono);
  font-size: var(--font-size-sm);
  background: var(--background-secondary);
  border-radius: var(--radius-md);
  padding: var(--spacing-md);
}

.log-entry {
  padding: var(--spacing-xs) 0;
}

.log-entry.info { color: var(--info-color); }
.log-entry.warning { color: var(--warning-color); }
.log-entry.error { color: var(--error-color); }

.log-time {
  color: var(--text-tertiary);
  margin-right: var(--spacing-md);
}

.info-list {
  padding: var(--spacing-lg);
}

.info-item {
  margin-bottom: var(--spacing-lg);
}

.info-item:last-child {
  margin-bottom: 0;
}

.info-item label {
  display: block;
  color: var(--text-tertiary);
  font-size: var(--font-size-sm);
  margin-bottom: var(--spacing-xs);
}

.value-with-copy {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
}

.status-metrics {
  padding: var(--spacing-lg);
}

.metric {
  margin-bottom: var(--spacing-lg);
}

.metric:last-child {
  margin-bottom: 0;
}

.metric-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--spacing-sm);
}

.metric-value {
  font-weight: var(--font-weight-medium);
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--spacing-md);
  padding: var(--spacing-lg);
}

.stat-item {
  text-align: center;
  padding: var(--spacing-md);
  background: var(--background-tertiary);
  border-radius: var(--radius-lg);
}

.stat-value {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-semibold);
  margin-bottom: var(--spacing-xs);
}

.stat-value.success { color: var(--success-color); }
.stat-value.failed { color: var(--error-color); }

.stat-label {
  color: var(--text-tertiary);
  font-size: var(--font-size-sm);
}

.rollback-dialog-content {
  text-align: center;
  padding: var(--spacing-xl) 0;
}

.warning-icon {
  font-size: 48px;
  color: var(--warning-color);
  margin-bottom: var(--spacing-lg);
}

.warning-text {
  color: var(--text-tertiary);
  font-size: var(--font-size-sm);
  margin-top: var(--spacing-sm);
}

@media (max-width: 1200px) {
  .content-grid {
    grid-template-columns: 1fr;
  }
}
</style> 